/*       D-Day: Normandy by Vipersoft
 ************************************
 *   $Source: /usr/local/cvsroot/dday/src/pol/pol_weapon.c,v $
 *   $Revision: 1.13 $
 *   $Date: 2002/07/23 07:26:15 $
 * 
 ***********************************

Copyright (C) 2002 Vipersoft

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "pol_main.h"

// p_weapon.c
// D-Day: Normandy Player Weapon Code


/*
void Weapon_Generic (edict_t *ent, 
 int FRAME_ACTIVATE_LAST,	int FRAME_LFIRE_LAST,	int FRAME_LIDLE_LAST, 
 int FRAME_RELOAD_LAST,		int FRAME_LASTRD_LAST,	int FRAME_DEACTIVATE_LAST,
 int FRAME_RAISE_LAST,		int FRAME_AFIRE_LAST,	int FRAME_AIDLE_LAST,
 int *pause_frames,			int *fire_frames,		void (*fire)(edict_t *ent))
*/


//faf:  gotta move fire_gun in here like this
void fire_gun2(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod, qboolean calcv)
{
	// standard defines
	trace_t		tr;
	vec3_t		dir;
	vec3_t		forward, right, up;
	vec3_t		end;
	float		r;
	float		u;
	vec3_t		water_start;
	qboolean	water = false;
	int			content_mask = MASK_SHOT | MASK_WATER;

	// rezmoth - start dist trace
	vec3_t	diststart, dist;
	vec3_t	distend = {0, 0, -8192};
	trace_t	disttr;

	VectorCopy(self->s.origin, diststart);	// initial value
	//VectorAdd(start, ent->mins, start); // go to the bottom of the player
	VectorAdd(diststart, distend, distend);			// add distance for end

	disttr = ptrgi->trace (diststart, self->mins, self->maxs, distend, self, MASK_SOLID);
	VectorSubtract(self->s.origin, disttr.endpos, dist);
	// rezmoth - end dist trace

	// Extra debugging propaganda
	//gi.dprintf("self    %s\n", self->client->pers.netname);
	//gi.dprintf("damage  %i\n", damage);
	//gi.dprintf("kick    %i\n", kick);
	//gi.dprintf("mod     %i\n", mod);
	//gi.dprintf("calcv   %s\n", (calcv) ? "true":"false");

	// Useful debugging information
	//gi.dprintf("hspread %i\n", hspread);
	//gi.dprintf("vspread %i\n", vspread);
	//showvector("start   ", start);
	//showvector("aimdir  ", aimdir);

	// fetch trace results
	tr = ptrgi->trace(self->s.origin, NULL, NULL, start, self, MASK_SHOT);

	// if the trace hit anything before distance termination
	if (!(tr.fraction < 1.0))
	{
		// seperate the aimdir into three parts
		vectoangles(aimdir, dir);
		AngleVectors(dir, forward, right, up);

		// rezmoth - TODO: fix this part
		// random spread calculation
		calcv = false;
		//r = (calcv) ? (crandom() * hspread) : hspread;
		//u = (calcv) ? (crandom() * vspread) : vspread;

		// add spread to hip shots
		if (!self->client->aim)
		{
			r = crandom() * 600;
			u = crandom() * 600;
		} else {
			r = crandom() * 50;
			u = crandom() * 50;
		}

		if (VectorLength(dist) > 20 && self->velocity[2] != 0)
		{
			r = crandom() * 1600;
			u = crandom() * 1600;
		}

		// end = start[i] + 8192 * forward[i]
		VectorMA (start, 8192, aimdir, end);//forward, end);
		// scale right angle by calculated horizontal spread
		VectorMA (end, r, right, end);
		// scale up angle by calculated vertical spread
		VectorMA (end, u, up, end);

		// if trace starts in water?
		if (ptrgi->pointcontents (start) & MASK_WATER)
		{
			water = true;
			VectorCopy (start, water_start);
			// remove water from possible impacts during trace
			content_mask &= ~MASK_WATER;
		}

		// retrace from point of impact with water
		tr = ptrgi->trace (start, NULL, NULL, end, self, content_mask);

		// if trace impacts dead player

//faf	if (tr.contents & MASK_DEADSOLID)
//faf		SprayBlood(self, tr.endpos, up, 0, MOD_UNKNOWN);
//faf:  sprayblood wont work here


		// more spread calculation
		if(calcv) calcVspread(self,&tr);

		// if the trace impacts water?
		if (tr.contents & MASK_WATER)
		{
			int		color;
			water = true;

			// copy trace's impact with water (end) to water_start
			VectorCopy (tr.endpos, water_start);

			// if the trace's start and end were not the same
			if (!VectorCompare (start, tr.endpos))
			{
				// if trace impacts water
				if (tr.contents & CONTENTS_WATER)
				{
					// if water is brown
					if (strcmp(tr.surface->name, "*brwater") == 0)
						color = SPLASH_BROWN_WATER;
					// if water is blue
					else
						color = SPLASH_BLUE_WATER;
				}
				// if trace impacts slime
				else if (tr.contents & CONTENTS_SLIME)
					color = SPLASH_SLIME;
				// if trace impacts lava
				else if (tr.contents & CONTENTS_LAVA)
					color = SPLASH_LAVA;
				// if trace impacts unknown water
				else
					color = SPLASH_UNKNOWN;

				// if trace impacted known water
				if (color != SPLASH_UNKNOWN)
				{
					// display water splash particles
					ptrgi->WriteByte (svc_temp_entity);
					ptrgi->WriteByte (TE_SPLASH);
					ptrgi->WriteByte (8);
					ptrgi->WritePosition (tr.endpos);
					ptrgi->WriteDir (tr.plane.normal);
					ptrgi->WriteByte (color);
					ptrgi->multicast (tr.endpos, MULTICAST_PVS);
				}

				// change bullet's course when it enters water
				VectorSubtract (end, start, dir);
				vectoangles (dir, dir);
				AngleVectors (dir, forward, right, up);
				r = crandom()*hspread*2;
				u = crandom()*vspread*2;
				VectorMA (water_start, 8192, aimdir, end);//faf forward, end);
				VectorMA (end, r, right, end);
				VectorMA (end, u, up, end);
			}

			// retrace starting from impact with water
			tr = ptrgi->trace (water_start, NULL, NULL, end, self, MASK_SHOT);
		}
	}

	// if trace does not impact a surface and the surface is not the sky
	if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
	{
		// if the trace impacted anything before distance termination
		if (tr.fraction < 1.0)
		{
			// if the impacted player can take damage
			if (tr.ent->takedamage)
			{
				// damage impacted player
				T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_BULLET, mod);
			}
			else
			{
				// if the trace impacted a surface other than the sky
				if (strncmp (tr.surface->name, "sky", 3) != 0)
				{
					// display impact on surface
					ptrgi->WriteByte (svc_temp_entity);
					if (crandom() < 0.5)
						ptrgi->WriteByte (TE_GUNSHOT);
					else
						ptrgi->WriteByte (TE_BULLET_SPARKS);
					ptrgi->WritePosition (tr.endpos);
					ptrgi->WriteDir (tr.plane.normal);
					ptrgi->multicast (tr.endpos, MULTICAST_PVS);

					// output impact sound
					if (self->client)
						PlayerNoise(self, tr.endpos, PNOISE_IMPACT);
//						ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex(guninfo->FireSound), 1, ATTN_NORM, 0);//faf

											
				}
			}
		}
	}

	// if trace impacted water
	if (water)
	{
		vec3_t	pos;

		VectorSubtract (tr.endpos, water_start, dir);
		VectorNormalize (dir);
		VectorMA (tr.endpos, -2, dir, pos);
		if (ptrgi->pointcontents (pos) & MASK_WATER)
			VectorCopy (pos, tr.endpos);
		else
			tr = ptrgi->trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER);

		VectorAdd (water_start, tr.endpos, pos);
		VectorScale (pos, 0.5, pos);

		// display bubble trail
		ptrgi->WriteByte (svc_temp_entity);
		ptrgi->WriteByte (TE_BUBBLETRAIL);
		ptrgi->WritePosition (water_start);
		ptrgi->WritePosition (tr.endpos);
		ptrgi->multicast (pos, MULTICAST_PVS);
	}
} 

/////////////////////////////////////////////////
// Vis
/////////////////////////////////////////////////

void Weapon_Vis (edict_t *ent)
{
	static int	pause_frames[]	= {0};//{13, 32,42};
	static int	fire_frames[1];	//= {4,59,0};

	fire_frames[0]=(ent->client->aim)?71:4;

	ent->client->p_fract= &ent->client->mags[pol_index].pistol_fract;
	ent->client->p_rnd= &ent->client->mags[pol_index].pistol_rnd;

	ent->client->crosshair = false;

if ((ent->client->weaponstate == WEAPON_FIRING || ent->client->weaponstate == WEAPON_READY)
			&& !ent->client->heldfire && (ent->client->buttons & BUTTON_ATTACK)
			&& ent->client->ps.gunframe!=((ent->client->aim)?70:3)
			&& ent->client->ps.gunframe!=((ent->client->aim)?71:4)
			&& ent->client->ps.gunframe!=((ent->client->aim)?72:5)
			&& ent->client->ps.gunframe!=((ent->client->aim)?73:6)
			//gotta do it this way for both firing modes
)
		{
			if (ent->client->ps.gunframe<4)
//				firetype = abs(5-ent->client->ps.gunframe);  unknown function
			ent->client->ps.gunframe = 4;
			ent->client->weaponstate = WEAPON_READY;
			ent->client->latched_buttons |= BUTTON_ATTACK;
			ent->client->heldfire = true;
		}
		else
		{
			ent->client->buttons &= ~BUTTON_ATTACK;
			ent->client->latched_buttons &= ~BUTTON_ATTACK;
		}
//else
//		ent->client->heldfire = false;  // have to comment out or else semi-auto doesn't work

	Weapon_Generic (ent, 
		3,  6,  47, 
		58, 61, 65, 
		70, 73, 84, 
		
		pause_frames, fire_frames, Weapon_Pistol_Fire);
}


void Weapon_SVT (edict_t *ent)
{
	static int	pause_frames[]	= {0};//{47, 80};
	static int	fire_frames[1];
	
	fire_frames[0] = (ent->client->aim)?76:4;

	// Wheaty: Uncomment next line to allow topping off
	//ent->client->p_fract = &ent->client->mags[usa_index].rifle_fract
	ent->client->p_rnd= &ent->client->mags[pol_index].rifle_rnd;

	ent->client->crosshair = false;

if ((ent->client->weaponstate == WEAPON_FIRING || ent->client->weaponstate == WEAPON_READY)
			&& !ent->client->heldfire && (ent->client->buttons & BUTTON_ATTACK)
			&& ent->client->ps.gunframe!=((ent->client->aim)?75:3)
			&& ent->client->ps.gunframe!=((ent->client->aim)?76:4)
			&& ent->client->ps.gunframe!=((ent->client->aim)?77:5)
			&& ent->client->ps.gunframe!=((ent->client->aim)?78:6)
			//gotta do it this way for both firing modes
)
		{
			if (ent->client->ps.gunframe<4)
//				firetype = abs(5-ent->client->ps.gunframe);  unknown function
			ent->client->ps.gunframe = 4;
			ent->client->weaponstate = WEAPON_READY;
		//	ent->client->latched_buttons |= BUTTON_ATTACK;
			ent->client->heldfire = true;
		}
		else
		{
			ent->client->buttons &= ~BUTTON_ATTACK;
			ent->client->latched_buttons &= ~BUTTON_ATTACK;
		}
//else
//		ent->client->heldfire = false;  // have to comment out or else semi-auto doesn't work



//faf: bayonet code
	if (ent->client->ps.gunframe == 93)
	{
		ent->client->ps.gunframe = 10;
		return;
	}

	if (ent->client->ps.gunframe > 89)
	{
		ent->client->ps.gunframe++;
		return;
	}
//end bayonet




	Weapon_Generic (ent, 
		 3,  6, 47, 
		64, 67, 72, 
		75, 78, 89, 
		
		pause_frames, fire_frames, Weapon_Rifle_Fire);

}
/*
/////////////////////////////////////////////////
// Sten
/////////////////////////////////////////////////

void Weapon_Sten_Fire (edict_t *ent)
{
	int	i;
	vec3_t		start;
	vec3_t		forward, right;
	vec3_t		angles;
	int			kick = 2;
	vec3_t		offset;
	GunInfo_t *guninfo=ent->client->pers.weapon->guninfo;	
	int mag_index=ent->client->pers.weapon->mag_index;
	int mod=guninfo->MeansOfDeath;
	int	damage = guninfo->damage_direct;


	int randnum; //faf

	srand(rand());
	randnum=rand()%300;

	if (ent->client->next_fire_frame > ptrlevel->framenum)
		return;

	if (!(ent->client->buttons & BUTTON_ATTACK))
	{
		ent->client->machinegun_shots = 0;
		ent->client->ps.gunframe++;
		return;
	}

	if(ent->client->aim)
	{
		if (ent->client->ps.gunframe == guninfo->LastAFire)
			ent->client->ps.gunframe = guninfo->LastAFire-1;
		else
			ent->client->ps.gunframe = guninfo->LastAFire;
	}

	else
	{
		if (ent->client->ps.gunframe == guninfo->LastFire)
			ent->client->ps.gunframe = guninfo->LastFire-1;
		else
			ent->client->ps.gunframe = guninfo->LastFire;
	}

	if (!ent->client->mags[mag_index].submg_rnd)
	{
		ent->client->ps.gunframe = (ent->client->aim)?guninfo->LastAFire+1:guninfo->LastFire+1;
	
		if (ptrlevel->time >= ent->pain_debounce_time)
		{
			ptrgi->sound(ent, CHAN_VOICE, ptrgi->soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = ptrlevel->time + 1;
		}
		
		
		return;
	}

	if (!ent->client->aim)
	{
		for (i=0 ; i<3 ; i++)
		{
			// Thompson extra-kick (1.7 to 1.9)
			// rezmoth - changed for new firing system
			//ent->client->kick_origin[i] = (crandom() * 0.5)-1.5;
			//ent->client->kick_angles[i] = (crandom() * 1.9)-1.5;
		}

		// rezmoth - changed for new firing system
		//ent->client->kick_origin[0] = crandom() * 0.38;
		//ent->client->kick_angles[0] = ent->client->machinegun_shots * -1.8;

	}
	else
	{
		for (i=1 ; i<3 ; i++)
		{	
			// rezmoth - changed for new firing system
			//ent->client->kick_origin[i] = crandom() * 0.35;
			//ent->client->kick_angles[i] = crandom() * 0.7;
		}

		// rezmoth - changed for new firing system
		//ent->client->kick_origin[0] = crandom() * 0.35;
		//ent->client->kick_angles[0] = ent->client->machinegun_shots * -1.5;
	}

	// raise the gun as it is firing
//	if (!deathmatch->value)
//	{
	ent->client->machinegun_shots++;
	if (ent->client->machinegun_shots > 9)
		ent->client->machinegun_shots = 9;
//	}

	// vspread
	//VectorSet(offset, 0, (ent->client->aim)?0:8, ent->viewheight-8 + (crandom() * 15));
	// rezmoth - changed for new firing system
	//VectorSet(offset, 0, (ent->client->aim)?0:8, (ent->client->aim)?ent->viewheight-8:crandom() * 15);
	if (ent->client->pers.weapon->position == LOC_SUBMACHINEGUN)
		VectorSet(offset, 0, 0, ent->viewheight - 0);	//10
	else
		ptrgi->dprintf("*** Firing System Error\n");

//faf for testing	ptrgi->cprintf(ent, PRINT_HIGH, "%i randnum\n", randnum);

//	jamchance = rand() % 100;
	if (randnum == 5)
	{
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
		ptrgi->centerprintf(ent, "Your gun jammed!\n");
		ent->client->mags[mag_index].submg_rnd= 0;
		return;
	}


	// rezmoth - cosmetic recoil
	if (ptrlevel->framenum % 3 == 0)
	{
		if (ent->client->aim)
			ent->client->kick_angles[0] -= 1.5;
		else
			ent->client->kick_angles[0] = -3;
	}

	// pbowens: for darwin's 3.2 kick
	ent->client->kick_angles[0] = ent->client->machinegun_shots * -1;
	ent->client->kick_angles[1] = ent->client->machinegun_shots * .3;

	// get start / end positions
	VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
	AngleVectors (angles, forward, right, NULL);
	
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);


	fire_gun2(ent, start, forward, damage, kick, 0, 0, mod, false);

	if(ent->client->mags[mag_index].submg_rnd==1)
	{
		//Hard coded for reload only.
        ent->client->ps.gunframe=guninfo->LastReload+1;
        ent->client->weaponstate = WEAPON_END_MAG;
//		Play_WepSound(ent,guninfo->LastRoundSound);
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex(guninfo->LastRoundSound), 1, ATTN_NORM, 0);//faf

	
	}

	// rezmoth - changed to new firing code
	//fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, mod, false);

  
	//gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/machgf2b.wav"), 1, ATTN_NORM, 0);


//	Play_WepSound(ent,guninfo->FireSound);//PlayerNoise(ent, start, PNOISE_WEAPON);
	ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex(guninfo->FireSound), 1, ATTN_NORM, 0);//faf

	
	
	ptrgi->WriteByte (svc_muzzleflash);
	ptrgi->WriteShort (ent-g_edicts);
	ptrgi->WriteByte (MZ_MACHINEGUN);//faf | is_silenced);
	ptrgi->multicast (ent->s.origin, MULTICAST_PVS);

	ent->client->mags[mag_index].submg_rnd--;
	ent->client->next_fire_frame = ptrlevel->framenum + guninfo->frame_delay;
}

void Weapon_Sten (edict_t *ent)
{

	static int	pause_frames[]	= {0};
	static int	fire_frames[2];//try to put stutter back in

	fire_frames[0]=(ent->client->aim)?79:4;
	fire_frames[1]=(ent->client->aim)?80:5;

	ent->client->p_fract= &ent->client->mags[pol_index].submg_fract;
	ent->client->p_rnd= &ent->client->mags[pol_index].submg_rnd;

	ent->client->crosshair = false;

	Weapon_Generic (ent, 
		 3,  5, 45, 
		71, 71, 75,
		78, 80, 92, 
		
		pause_frames, fire_frames, Weapon_Sten_Fire);

}

*/

/////////////////////////////////////////////////
// RKM
/////////////////////////////////////////////////

void Weapon_RKM (edict_t *ent)
{
	static int	pause_frames[]	= {0};//{23, 45, 0};
	static int	fire_frames[2];

	fire_frames[0]=(ent->client->aim)?77:4;
	fire_frames[1]=(ent->client->aim)?78:5;

	ent->client->p_fract= &ent->client->mags[pol_index].lmg_fract;
	ent->client->p_rnd= &ent->client->mags[pol_index].lmg_rnd;

	ent->client->crosshair = false;

	Weapon_Generic (ent, 
		 3,  5, 44,
		69, 69, 73,
		76, 78, 89,
		
		pause_frames, fire_frames, Weapon_LMG_Fire);
}


/////////////////////////////////////////////////
// MG34
/////////////////////////////////////////////////
void Weapon_MG34_Fire (edict_t *ent)
{
	int			i;
	int			shots=1;
	vec3_t		start;
	vec3_t		forward, right, up;
	vec3_t		offset;
	vec3_t		angles;
	int			kick = 30;
	GunInfo_t *guninfo=ent->client->pers.weapon->guninfo;	
	int mag_index=ent->client->pers.weapon->mag_index;
	int mod=guninfo->MeansOfDeath;
	int	damage=guninfo->damage_direct;
	trace_t tr; //faf
    vec3_t end; //faf
	vec3_t g_offset; //faf


	if (ent->client->next_fire_frame > ptrlevel->framenum)
		return;

	//Wheaty: Disable HMG while standing, totally
	//faf:  hmgers can now rest hmg on sandbags/objects in front of them
	if (ent->stanceflags == STANCE_STAND && (ent->client->buttons & BUTTON_ATTACK))
	{
		VectorCopy (vec3_origin,g_offset);

	    AngleVectors (ent->client->v_angle, forward, right, NULL);
	    VectorSet(offset, 24, 8, ent->viewheight-25);
	    VectorAdd (offset, g_offset, offset);
	    P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
	    VectorScale (forward, -2, ent->client->kick_origin);
		
		VectorMA (start, 5, forward, end);  //calculates the range vector  //faf: 10 = range
		tr = ptrgi->trace (ent->s.origin, NULL, NULL, end, ent, MASK_SHOT);// figures out what in front of the player up till "end"

		if (tr.fraction >= 1.0 ||
			ent->client->v_angle[0] > 40)
		{
			ptrgi->cprintf(ent, PRINT_HIGH, "You need to rest that thing on something to shoot it!\n");
			return;
		}
	}

// this is for when the trigger is released
	if (!(ent->client->buttons & BUTTON_ATTACK))
	{
		if (!ent->client->aim)
			ent->client->ps.gunframe = guninfo->LastFire;
		else 
			ent->client->ps.gunframe=guninfo->LastAFire;

		ent->client->weapon_sound = 0;
		ent->client->machinegun_shots=0;
		
		ent->client->buttons &= ~BUTTON_ATTACK;
		ent->client->latched_buttons &= ~BUTTON_ATTACK;
		ent->client->weaponstate = WEAPON_READY;

		return;
	}



	// pbowens: the following assumes HMGs use only 2 firing frames
	i = (ptrlevel->framenum % 2) ? 1 : 0;

	if (ent->client->aim)
		ent->client->ps.gunframe = guninfo->AFO[i];
	else
		ent->client->ps.gunframe = guninfo->FO[i];


	if (ent->client->p_rnd && *ent->client->p_rnd <= 0)
	{
		if (ent->client->weaponstate != WEAPON_FIRING)
			return;

		if (ptrlevel->time >= ent->pain_debounce_time)
		{
			ptrgi->sound(ent, CHAN_VOICE, ptrgi->soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
			ent->pain_debounce_time = ptrlevel->time + 1;
		}


		 if (ent->client->aim) 
			 ent->client->ps.gunframe = guninfo->LastAFire;
		 else 
			 ent->client->ps.gunframe = guninfo->LastFire;

		 ent->client->weaponstate = WEAPON_READY;

		 return;
	}

	//ent->client->ps.gunframe++;

	// get start / end positions
	
	//if not crouched, make gun jump sporadicly
//faf	if (ent->stanceflags == STANCE_STAND || !ent->client->aim)
	if (!ent->client->aim)
	{	
		for (i=0 ; i<3 ; i++)
		{
			//rezmoth - changed for new firing system
			ent->client->kick_origin[i] = (crandom() * 3.35)-1.5;
			ent->client->kick_angles[i] += (crandom() * 13.7)-1.5;
		}
		//rezmoth - changed for new firing system
		ent->client->kick_origin[0] = crandom() * 0.35;
		ent->client->kick_angles[0] += ent->client->machinegun_shots * -1.8;
		// Raise HMG faster
		ent->client->machinegun_shots += 2;
		VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
		AngleVectors (angles, forward, right, up);
	}
	
	else
	{
		for (i=0 ; i<3 ; i++)
		{
			//rezmoth - changed for new firing system
			ent->client->kick_origin[i] = crandom() * 0.35;
			ent->client->kick_angles[i] += crandom() * 0.7;
		}
		VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
		AngleVectors (angles, forward, right, up);
	}
	
	// Instead of limit, force the aim down and start over for jumpiness
	if (ent->client->machinegun_shots > 10)
		ent->client->machinegun_shots -= 10;


		VectorSet(offset, 0, 0, ent->viewheight - 0);
		P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

		// rezmoth - tracers moved to here
		//fire_bullet (ent, start, forward, damage, kick, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, mod, true);
		++ent->numfired;

//		if (ent->numfired % TRACERSHOT == 1)
//			fire_tracer (ent, start, forward, damage, mod);
//		else
//			fire_gun(ent, start, forward, damage, kick, 0, 0, mod, false);
			fire_gun2(ent, start, forward, damage, kick, 0, 0, mod, false);

		
		//faf:  fire 2 bullets.  to simulate 900 rpm firing rate ****************
		if (ent->numfired % 2 == 1)
		{
			for (i=0 ; i<3 ; i++)
			{
				//rezmoth - changed for new firing system
				ent->client->kick_origin[i] = crandom() * 0.35;
				ent->client->kick_angles[i] += crandom() * 0.7;
			}
			VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
			AngleVectors (angles, forward, right, up);
			
			VectorSet(offset, 0, 0, ent->viewheight - 0);
			P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

			fire_gun2(ent, start, forward, damage, kick, 0, 0, mod, false);
		}
		//**********************************************************************




//	Play_WepSound(ent,guninfo->FireSound);//PlayerNoise(ent, start, PNOISE_WEAPON);
	if (ent->numfired % 2 == 1)
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/mg34/firea.wav"), 1, ATTN_NORM, 0);//faf
	else
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/mg34/fireb.wav"), 1, ATTN_NORM, 0);//faf

	// send muzzle flash
	ptrgi->WriteByte (svc_muzzleflash);
	ptrgi->WriteShort (ent-g_edicts);
	ptrgi->WriteByte (MZ_MACHINEGUN);// | is_silenced);
	ptrgi->multicast (ent->s.origin, MULTICAST_PVS);


	if (ent->numfired % 2 == 1)
		ent->client->mags[mag_index].hmg_rnd-= 2;
	else
		ent->client->mags[mag_index].hmg_rnd-= 1;

	ent->client->next_fire_frame = ptrlevel->framenum + guninfo->frame_delay;

}

void Weapon_MG34 (edict_t *ent)
{
	static int	pause_frames[]	= {0};//{38, 61, 0};
	static int	fire_frames[2];

//	fire_frames[0]=(ent->client->aim)?99:20;
	fire_frames[0]=(ent->client->aim)?86:21;
	fire_frames[1]=(ent->client->aim)?87:22;

	ent->client->p_rnd= &ent->client->mags[pol_index].hmg_rnd;

	ent->client->crosshair = false;

	if (ent->client->ps.gunframe == 7)
	ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/vickers/bolt.wav"), 1, ATTN_NORM, 0);

	Weapon_Generic (ent, 
		20, 22, 62, 
		79, 79, 82, 
		85, 87, 99, 
		
		pause_frames, fire_frames, Weapon_MG34_Fire);
}



/////////////////////////////////////////////////
// PIAT
/////////////////////////////////////////////////

//faf:  adds gravity to the rocket
void fire_rocket2 (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage)
{
	edict_t	*rocket;

	rocket = G_Spawn();
	VectorCopy (start, rocket->s.origin);
	VectorCopy (dir, rocket->movedir);
	vectoangles (dir, rocket->s.angles);
	VectorScale (dir, speed, rocket->velocity);
	rocket->movetype = MOVETYPE_BOUNCE,//MOVETYPE_FLYMISSILE;
	rocket->clipmask = MASK_SHOT;
	rocket->solid = SOLID_BBOX;
	//rocket->s.effects |= EF_ROCKET;
	VectorClear (rocket->mins);
	VectorClear (rocket->maxs);
	rocket->s.modelindex = ptrgi->modelindex ("models/objects/rocket/tris.md2");
	rocket->owner = self;
	rocket->touch = rocket_touch;
	rocket->nextthink = ptrlevel->time + 8000/speed;
	rocket->think = G_FreeEdict;
	rocket->dmg = damage;
	rocket->radius_dmg = radius_damage;
	rocket->dmg_radius = damage_radius;
	rocket->s.sound = ptrgi->soundindex ("weapons/rockfly.wav");
	rocket->classname = "rocket";
	
	rocket->gravity =  1;//.9; //faf


//faf:causing error and dont think is needed	if (self->client)
//faf		check_dodge (self, rocket->s.origin, dir, speed);

	ptrgi->linkentity (rocket);
}
void Weapon_PIAT_Fire (edict_t *ent)
{

	vec3_t	offset, start;
	vec3_t	forward, right;

	GunInfo_t *guninfo=ent->client->pers.weapon->guninfo;	
	int mag_index=ent->client->pers.weapon->mag_index;
	int mod=guninfo->MeansOfDeath;
	int	radius_damage = guninfo->damage_radius; //The *damage* within the radius
	int	damage		= guninfo->damage_direct;

	float	damage_radius; // The *radius* of the damage

	// Nick 28/11/2002 - flag for incorrect firing.
	short int		firewrong;
	firewrong = 0;


//faf: for testing	ptrgi->bprintf (PRINT_HIGH, "%i machinegun shots\n", ent->client->machinegun_shots); 

	if (ent->client->next_fire_frame > ptrlevel->framenum)
		return;

	// Nick 28/11/2002 - Tidied up the warnings somewhat (i.e. made it specific to the problem).
	// and of course 'Bristishised' them :).

	// Remove the old warnings first.

	//	if (ent->stanceflags == STANCE_STAND 
	//	ent->stanceflags == STANCE_CRAWL ||
	//	ent->client->movement			 ||
	//   !ent->client->aim				 ||
	//    ptrgi->pointcontents(ent->s.origin) & MASK_WATER) //Wheaty: Don't let them fire in water
	//{
	//	ptrgi->cprintf(ent, PRINT_HIGH, "You must kneel (crouch), be on dry land, and aim before firing that thing!\n");
		


		// Add the new ones.
		if (ptrgi->pointcontents(ent->s.origin) & MASK_WATER) {
			if (ent->client->machinegun_shots == 0)
				ptrgi->centerprintf(ent, "Get out the water to fire!\n");
			firewrong = 1;
			ent->client->machinegun_shots = 1;
				}

		else if (!ent->client->aim) {

//			if (ent->client->machinegun_shots == 0)
//				ptrgi->centerprintf(ent, "You have to aim!\n");
			firewrong = 1;
			ent->client->machinegun_shots = 1;

				}



		else if ((ent->stanceflags == STANCE_STAND) || (ent->stanceflags == STANCE_CRAWL)) {

			if (ent->client->machinegun_shots == 0)
				ptrgi->centerprintf(ent, "You have to kneel!\n");
			firewrong = 1;
			ent->client->machinegun_shots = 1;

				}

		//else if (ent->stanceflags == STANCE_CRAWL) {
		//	if (ent->client->machinegun_shots == 0)
		//		ptrgi->centerprintf(ent, "Get up on one knee, Tommy Atkins!!\n");
		//	firewrong = 1;
		//	ent->client->machinegun_shots = 1;
		//		}

		if (firewrong == 1) {
		//gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"),1, ATTN_NORM, 0);
		//ent->pain_debounce_time = level.time + 1;
		//ent->client->ps.gunframe= (ent->client->aim)?guninfo->LastAFire + 1:
		//													guninfo->LastFire + 1;

		// Nick - 25/11/2002 Had to add this to allow the new 'empty' idle frames to work here.

			if (ent->client->mags[mag_index].antitank_rnd == 0) {
			ent->client->ps.gunframe = 46;
			} else {
			// Original code follows.
			ent->client->ps.gunframe= (ent->client->aim)?guninfo->LastAFire + 1:
															guninfo->LastFire + 1;
			}
		// End Nick

 		ent->client->weapon_sound = 0;
		ent->client->weaponstate=WEAPON_READY;
		return;
	}

	if (!(ent->client->buttons & BUTTON_ATTACK))
	{
		if (ent->client->aim)
			ent->client->ps.gunframe = guninfo->LastAFire+1;
		else
			ent->client->ps.gunframe = guninfo->LastFire+1;
		return;
	}

	// pbowens: rasied rocket dmg from 175 to 225
	damage_radius = 175;//faf 225;

	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorScale (forward, -2, ent->client->kick_origin);
	//ent->client->kick_angles[0] = -1;

	VectorSet(offset, 8, 8, ent->viewheight-8);			//z,x,y
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

	if (!ent->client->mags[mag_index].antitank_rnd)
	 {

		ent->client->ps.gunframe = (ent->client->aim) ? guninfo->LastAFire+1 : guninfo->LastFire+1;
		 if (ptrlevel->time >= ent->pain_debounce_time)
		 {
			 ptrgi->sound(ent, CHAN_VOICE, ptrgi->soundindex("weapons/noammo.wav"),1, ATTN_NORM, 0);
			 ent->pain_debounce_time = ptrlevel->time + 1;
		 }

//		if (auto_reload->value)
//			Cmd_Reload_f(ent);

		return;
	}

	/*faf removed
	if (ent->client->mags[mag_index].antitank_rnd == 1) { // last round fire sounds

		//Hard coded for reload only.
        ent->client->ps.gunframe=guninfo->LastReload+1;
        ent->client->weaponstate = WEAPON_END_MAG;
//		Play_WepSound(ent,guninfo->LastRoundSound);
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex(guninfo->LastRoundSound), 1, ATTN_NORM, 0);//faf

	} */
/*
	if (ent->client->pers.inventory[ent->client->ammo_index] == 1)
	{
		//Hard coded for reload only.
        ent->client->ps.gunframe=guninfo->LastReload+1;
        ent->client->weaponstate = WEAPON_END_MAG;
		Play_WepSound(ent,guninfo->LastRoundSound);
	}

	if (!ent->client->pers.inventory[ent->client->ammo_index])
	{
		ent->client->ps.gunframe = guninfo->LastFire;
		
		if (level.time >= ent->pain_debounce_time)
		{
			gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"),1, ATTN_NORM, 0);
			ent->pain_debounce_time = level.time + 1;
		}

		//Make the user change weapons MANUALLY!

		if(auto_weapon_change->value) 
			NoAmmoWeaponChange (ent);

		return;
	}
	*/

	fire_rocket2 (ent, start, forward, damage, 1600, damage_radius, radius_damage); //faf: was 1400 
	// rezmoth - cosmetic recoil
	ent->client->kick_angles[0] -= 7;
	ent->client->kick_origin[2] -= 5;

//	Play_WepSound(ent,guninfo->FireSound);//PlayerNoise(ent, start, PNOISE_WEAPON);
	ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex(guninfo->FireSound), 1, ATTN_NORM, 0);//faf

	// send muzzle flash
	ptrgi->WriteByte (svc_muzzleflash);
	ptrgi->WriteShort (ent-g_edicts);
	ptrgi->WriteByte (MZ_ROCKET);
	ptrgi->multicast (ent->s.origin, MULTICAST_PVS);
	
	ent->client->ps.gunframe++;


	//ent->client->pers.inventory[ent->client->ammo_index]--;
	ent->client->mags[mag_index].antitank_rnd--;
	ent->client->next_fire_frame = ptrlevel->framenum + guninfo->frame_delay;

}

void Weapon_PIAT (edict_t *ent)
{
	static int	pause_frames[]	= {0};
	static int	fire_frames[1];

	// Nick 25/11/2002 added next declare for empty barrel hack.
	int mag_index;

	mag_index = ent->client->pers.weapon->mag_index;

	fire_frames[0]=(ent->client->aim)?83:4;

	ent->client->p_rnd = &ent->client->mags[pol_index].antitank_rnd;

	ent->client->crosshair = false;


	//faf
	if (ent->client->ps.gunframe == 85)//(last fire)
	{
		ent->client->weaponstate = WEAPON_LOWER;
		ent->client->aim = false;
	}

// ptrgi->dprintf("%i\n",ent->client->ps.gunframe);

	// Nick 25/11/2002 - Hack to make the 'barrel' empty after firing a shell.
	// I added 10 extra 'empty' frames in the idle cycle, and if PIAT is not
	// loaded it will cycle through that as opposed to the 'loaded' frames.
	//  If this is used as a 'if else' logic test, the frames go wonky on reload animation.

		if (ent->client->mags[mag_index].antitank_rnd < 1) {

	Weapon_Generic (ent, 
		 3,  45, 56, 
		75, 75, 79, 
		82, 85, 96,
					
		pause_frames, fire_frames, Weapon_PIAT_Fire);
		} 

		if (ent->client->mags[mag_index].antitank_rnd > 0) {

		Weapon_Generic (ent, 
		 3,  5, 45, 
		75, 75, 79, 
		82, 85, 96,
					
		pause_frames, fire_frames, Weapon_PIAT_Fire);
	}
}


/////////////////////////////////////////////////
// Mauser 98(ks) Sniper Rifle
/////////////////////////////////////////////////

void Weapon_POL_m98ks (edict_t *ent)
{
	static int	pause_frames[]	= {0};
	static int	fire_frames[4];

	fire_frames[0]=(ent->client->aim)?52:4;//fire here
	fire_frames[1]=(ent->client->aim)?60:0;//sniper bolt
	fire_frames[2]=(ent->client->aim)?75:0;//sniper start zoom
	fire_frames[3]=(ent->client->aim)?80:0;//sniper end zoom

	ent->client->p_fract= &ent->client->mags[pol_index].sniper_fract;
	ent->client->p_rnd= &ent->client->mags[pol_index].sniper_rnd;

	if (ent->client->aim) 
	{
		if ( (ent->client->ps.gunframe >= fire_frames[0] && ent->client->ps.gunframe <= fire_frames[1]) ||
			  ent->client->ps.gunframe >= fire_frames[3])
			ent->client->crosshair = true;
		else
			ent->client->crosshair = false;
	} 
	else
		ent->client->crosshair = false;

	if ((ent->client->weaponstate == WEAPON_FIRING || ent->client->weaponstate == WEAPON_READY)
			&& !ent->client->heldfire && (ent->client->buttons & BUTTON_ATTACK)
			&& ent->client->ps.gunframe!=((ent->client->aim)?51:3)
			&& ent->client->ps.gunframe!=((ent->client->aim)?52:4)
			&& ent->client->ps.gunframe!=((ent->client->aim)?53:5)
			&& ent->client->ps.gunframe!=((ent->client->aim)?54:6)
			&& ent->client->ps.gunframe!=((ent->client->aim)?55:7)
			&& ent->client->ps.gunframe!=((ent->client->aim)?56:8)
			&& ent->client->ps.gunframe!=((ent->client->aim)?57:9)
			&& ent->client->ps.gunframe!=((ent->client->aim)?58:10)
			&& ent->client->ps.gunframe!=((ent->client->aim)?59:11)
			&& ent->client->ps.gunframe!=((ent->client->aim)?60:12)
			&& ent->client->ps.gunframe!=((ent->client->aim)?61:13)
			&& ent->client->ps.gunframe!=((ent->client->aim)?62:14)
			&& ent->client->ps.gunframe!=((ent->client->aim)?63:15)
			&& ent->client->ps.gunframe!=((ent->client->aim)?64:16)
			&& ent->client->ps.gunframe!=((ent->client->aim)?65:17)
			&& ent->client->ps.gunframe!=((ent->client->aim)?66:18)
			&& ent->client->ps.gunframe!=((ent->client->aim)?67:19)
			&& ent->client->ps.gunframe!=((ent->client->aim)?68:20)
			&& ent->client->ps.gunframe!=((ent->client->aim)?69:21)
			&& ent->client->ps.gunframe!=((ent->client->aim)?70:22)
			&& ent->client->ps.gunframe!=((ent->client->aim)?71:23)
			&& ent->client->ps.gunframe!=((ent->client->aim)?72:24)
			&& ent->client->ps.gunframe!=((ent->client->aim)?73:25)
			&& ent->client->ps.gunframe!=((ent->client->aim)?74:26)
			&& ent->client->ps.gunframe!=((ent->client->aim)?75:3)
			&& ent->client->ps.gunframe!=((ent->client->aim)?76:4)
			&& ent->client->ps.gunframe!=((ent->client->aim)?77:5)
			&& ent->client->ps.gunframe!=((ent->client->aim)?78:6)
			&& ent->client->ps.gunframe!=((ent->client->aim)?79:7)
			&& ent->client->ps.gunframe!=((ent->client->aim)?80:8)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?81:9)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?82:10)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?83:11)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?84:12)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?85:13)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?86:14)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?87:15)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?88:16)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?89:17)
//			&& ent->client->ps.gunframe!=((ent->client->aim)?90:18)

			//gotta do it this way for both firing modes
)
		{
			if (ent->client->ps.gunframe<4)
//				firetype = abs(5-ent->client->ps.gunframe);  unknown function
			ent->client->ps.gunframe = 4;
			ent->client->weaponstate = WEAPON_READY;
			ent->client->latched_buttons |= BUTTON_ATTACK;
			ent->client->heldfire = true;
		}
		else
		{
			ent->client->buttons &= ~BUTTON_ATTACK;
			ent->client->latched_buttons &= ~BUTTON_ATTACK;
		}
//else
//		ent->client->heldfire = false;  // have to comment out or else semi-auto doesn't work

	Weapon_Generic (ent, 
		 3, 26, 26, 
		43, 43, 48, 
		51, 80, 80, 
		
		pause_frames, fire_frames, Weapon_Sniper_Fire);
}


void Weapon_Mors (edict_t *ent)
{

	static int	pause_frames[]	= {0};
	static int	fire_frames[2];//try to put stutter back in

	fire_frames[0]=(ent->client->aim)?79:4;
	fire_frames[1]=(ent->client->aim)?80:5;

	ent->client->p_fract= &ent->client->mags[pol_index].submg_fract;
	ent->client->p_rnd= &ent->client->mags[pol_index].submg_rnd;

	ent->client->crosshair = false;

	Weapon_Generic (ent, 
		 3,  5, 45, 
		71, 71, 75, 
		78, 80, 92, 
		
		pause_frames, fire_frames, Weapon_Submachinegun_Fire);

}

qboolean fire_sabre ( edict_t *self, vec3_t start, vec3_t dir, int damage, int kick)
{    
    trace_t tr; //detect whats in front of you up to range "vec3_t end"

    vec3_t end;

	vec3_t	vec;
	float	dot;
	vec3_t	forward;


    // Figure out what we hit, if anything:

    VectorMA (start, 55, dir, end);  //calculates the range vector //50 is sword range
    tr = ptrgi->trace (self->s.origin, NULL, NULL, end, self, MASK_SHOT);
                        // figures out what in front of the player up till "end"
    
   // Figure out what to do about what we hit, if anything

    if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))    
    {
        if (tr.fraction < 1.0)        
        {            
            if (tr.ent->takedamage)            
            {

				if (tr.ent->client && 
					tr.ent->client->pers.weapon &&
					!strcmp(tr.ent->client->pers.weapon->classname, "weapon_sabre"))
				{
					AngleVectors (tr.ent->s.angles, forward, NULL, NULL);
					VectorSubtract (self->s.origin, tr.ent->s.origin, vec);
					VectorNormalize (vec);
					dot = DotProduct (vec, forward);
					//ptrgi->bprintf (PRINT_HIGH, "dot = %f \n",dot);
					if (dot > 0.6  &&
						tr.ent->client->weaponstate != WEAPON_FIRING)
					{
						if (random() < .5)	
							ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("pol/sabre/hit1.wav") , 1, ATTN_NORM, 0);
						else
							ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("pol/sabre/hit2.wav") , 1, ATTN_NORM, 0);
					}

					else
					{
						T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, 100, 50, 0,MOD_KNIFE);//faf
					  ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("brain/melee3.wav") , 1, ATTN_NORM, 0); 
					}

			
				}
				else
				{
					T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, 100, 50, 0,MOD_KNIFE);//faf
	                ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("brain/melee3.wav") , 1, ATTN_NORM, 0); 
				}

            }        
            else        
            {                
                ptrgi->WriteByte (svc_temp_entity);    
                ptrgi->WriteByte (TE_SPARKS);
                ptrgi->WritePosition (tr.endpos);    
                ptrgi->WriteDir (tr.plane.normal);
                ptrgi->multicast (tr.endpos, MULTICAST_PVS);

				if (random() < .5)	
					ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("pol/sabre/hit1.wav") , 1, ATTN_NORM, 0);
				else
					ptrgi->sound (self, CHAN_AUTO, ptrgi->soundindex("pol/sabre/hit2.wav") , 1, ATTN_NORM, 0);

            }    
			return true;
        }
    }
    return false;
} 
 


void Weapon_Sabre_Fire (edict_t *ent)
{
	vec3_t  forward, right;
    vec3_t  start;
    vec3_t  offset;
	vec3_t g_offset;

	vec3_t direction;

	ent->client->ps.gunframe++;//faf


	VectorCopy (vec3_origin,g_offset);

    AngleVectors (ent->client->v_angle, forward, right, NULL);
    VectorSet(offset, 24, 8, ent->viewheight-8);
    VectorAdd (offset, g_offset, offset);
    P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

    VectorScale (forward, -2, ent->client->kick_origin);
    ent->client->kick_angles[0] = -1;

	VectorAdd (forward, right, direction);
	VectorAdd (direction, forward, direction);
	VectorNormalize (direction);
 
	if (!(fire_sabre (ent, start, direction, 50, 0)))
	{
		VectorAdd (direction, forward, direction);
		VectorSubtract (forward, right, direction);
		VectorNormalize (direction);
		if (!(fire_sabre (ent, start, direction, 50, 0)))
		{
			if (!(fire_sabre (ent, start, forward, 50, 0)))
			{
				VectorAdd (direction, forward, direction);
				VectorSubtract (forward, right, direction);
				VectorNormalize (direction);
				if (!(fire_sabre (ent, start, direction, 50, 0)))
				{}
			}

		}

	}



	
	ent->client->ps.gunframe++;

	PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
}






void Weapon_Sabre (edict_t *ent)
{
	static int      pause_frames[]  = {0};//{19, 32, 0};
    int				fire_frames[] = {9,10};

	if (ent->client->aim)
		ent->client->aim = false;

	ent->client->crosshair = false;

	//ent->client->aim=false;
	//fire_frames[0]=(ent->client->aim)?54:4;
	ent->client->p_rnd=NULL;
	
	//faf
		fire_frames[0]=9;

		fire_frames[1] = 0;

	if(ent->client->ps.gunframe == 1)
		ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/sabre/draw.wav"), 1, ATTN_NORM, 0);//faf




	if (ent->client->ps.gunframe == 9)
	{
		ent->client->anim_priority = ANIM_REVERSE;
		if (ent->stanceflags == STANCE_STAND)
			{
				ent->s.frame = 66;//FRAME_pain304+1;
				ent->client->anim_end = 62;//FRAME_pain301;            
			}
			else if (ent->stanceflags == STANCE_DUCK)
			{
				ent->s.frame = 173;// FRAME_crpain4+1;
				ent->client->anim_end = 169;//FRAME_crpain1;
			}
			else if (ent->stanceflags == STANCE_CRAWL)
			{
				ent->s.frame = 234;// FRAME_crawlpain04+1;
				ent->client->anim_end = 230;//FRAME_crawlpain01;
			}
	}



	if(ent->client->ps.gunframe == 9)
	{
		if (random() < .333)	
		{
			ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/sabre/swing1.wav"), 1, ATTN_NORM, 0);
		}
		else if (random() < .5)	
		{
			ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/sabre/swing2.wav"), 1, ATTN_NORM, 0);
		}
		else
		{
			ptrgi->sound(ent, CHAN_WEAPON, ptrgi->soundindex("pol/sabre/swing3.wav"), 1, ATTN_NORM, 0);
		}
	}







	Weapon_Generic (ent, 
		7, 14, 29, 
		29,29,36,
		36,36,36, 
		pause_frames, fire_frames, Weapon_Sabre_Fire);
}


